<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>upload</title>
    <script src="js/jquery-3.4.1.js"></script>
</head>
<body>
<div id="uploader">
    <div class="btns">
        <input id="file" name="file" type="file"/>
        <br>
        <br>
        <button id="startBtn">
            开始上传
        </button>
        </br>
        </br>
    </div>
    <div id="output">
    </div>
</div>
</body>
<script type="text/javascript">
    var status = 0;
    var page = {
        init: function () {
            $("#startBtn").click($.proxy(this.upload, this));
        },
        upload: function () {
            status = 0;
            var GUID = this.guid();
            var file = $("#file")[0].files[0],  //文件对象
                name = file.name,        //文件名
                size = file.size;        //总大小
            var shardSize = 20 * 1024 * 1024,    //以1MB为一个分片
                shardCount = Math.ceil(size / shardSize);  //总片数
            for (var i = 0; i < shardCount; ++i) {
                //计算每一片的起始与结束位置
                var start = i * shardSize,
                    end = Math.min(size, start + shardSize);
                var partFile = file.slice(start, end);
                this.partUpload(GUID, partFile, name, shardCount, i);
            }
        },
        partUpload: function (GUID, partFile, name, chunks, chunk) {
            //构造一个表单，FormData是HTML5新增的
            var _this = this;
            var form = new FormData();
            form.append("guid", GUID);
            form.append("file", partFile);  //slice方法用于切出文件的一部分
            form.append("fileName", name);
            form.append("chunks", chunks);  //总片数
            form.append("chunk", chunk);        //当前是第几片
            //Ajax提交
            $.ajax({
                url: "http://localhost:8080/api/upload/part",
                type: "POST",
                data: form,
                async: true,        //异步
                processData: false,  //很重要，告诉jquery不要对form进行处理
                contentType: false,  //很重要，指定为false才能形成正确的Content-Type
                success: function (data) {
                    status++;
                    if (data.code == 200) {
                        $("#output").html(status + " / " + chunks);
                    }
                    if (status == chunks) {
                        _this.mergeFile(GUID, name);
                    }
                }
            });
        },
        mergeFile: function (GUID, name) {
            var formMerge = new FormData();
            formMerge.append("guid", GUID);
            formMerge.append("fileName", name);
            $.ajax({
                url: "http://localhost:8080/api/upload/merge",
                type: "POST",
                data: formMerge,
                processData: false,  //很重要，告诉jquery不要对form进行处理
                contentType: false,  //很重要，指定为false才能形成正确的Content-Type
                success: function (data) {
                    if (data.code == 200) {
                        alert('上传成功!');
                    }
                }
            });
        },
        guid: function (prefix) {
            var counter = 0;
            var guid = (+new Date()).toString(32),
                i = 0;
            for (; i < 5; i++) {
                guid += Math.floor(Math.random() * 65535).toString(32);
            }
            return (prefix || 'wu_') + guid + (counter++).toString(32);
        }
    };

    $(function () {
        page.init();
    });
</script>
</html>